#pragma once


/**
*@brief rect
*/
struct PXRect
{
	union
	{
		struct
		{
			LONG left;
			LONG top;
			LONG right;
			LONG bottom;
		};
		struct
		{
			LONG x;
			LONG y;
			LONG x2;
			LONG y2;
		};
	};
	PXRect();
	PXRect(LONG _left, LONG _top, LONG _right, LONG _bottom);
	LONG inline Width(void)const;
	LONG inline Height(void)const;

	// cast
	operator const RECT*()const;
	operator RECT*();
};



/**
*@brief rect
*/
template<class T>
class CPXRect
{
public:
	union
	{
		struct { T x, y, x2, y2; };
		struct { T left, top, right, bottom; };
	};

	CPXRect()
	{
	}
	CPXRect(const CPXRect<T>& v)
	{
		*this = v;
	}
	CPXRect(T _left, T _top, T _right, T _bottom):x(_left),y(_top),x2(_right),y2(_bottom)
	{
	}
	void SetRect(T _left, T _top, T _right, T _bottom)
	{
		x = _left;
		y = _top;
		x2 = _right;
		y2 = _bottom;
	}
	void SetRectSize(T _left, T _top, T _width, T _height)
	{
		x = _left;
		y = _top;
		x2 = x + _width;
		y2 = y + _height;
	}
	CPXRect& operator=(const CPXRect<T>& v)
	{
		memcpy( this, &v, sizeof(CPXRect<T>) );
		return *this;
	}
	BOOL operator==(const CPXRect& v) const
	{
		return !memcmp( this, &v, sizeof(CPXRect<T>) );
	}
	BOOL operator!=(const CPXRect& v) const
	{
		return memcmp( this, &v, sizeof(CPXRect<T>) );
	}
	T inline Left(void)const
	{
		return x;
	}
	T inline Right(void)const
	{
		return x2;
	}
	T inline Top(void)const
	{
		return y;
	}
	T inline Bottom(void)const
	{
		return y2;
	}
	T inline Width(void)const
	{
		return x2 - x;
	}
	T inline Height(void)const
	{
		return y2 - y;
	}

	// cast
	operator T*()
	{
		return &x;
	}
	operator const T*()const
	{
		return &x;
	}
};
